//
//  CLExtensionSecurity.h
//
//  Created by Charlie on 15/6/15.
//  Copyright (c) 2015年 . All rights reserved.
//

#import "CLSecurity.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

#pragma mark - Data Security

@implementation NSData (CLSecurity)

/// sha1加密函数 安全哈希算法
- (NSString *)sha1 {
    return [CLSecurityHelper sha1:self];
}

#pragma mark - RSA公钥加密算法

/// RSA公钥加密算法 加密
- (NSData *)encryptRSAWithPublicKey:(SecKeyRef)publicKey maxPlainLen:(size_t)maxPlainLen
{
    NSData *content = self;
    size_t plainLen = [content length];
    if (plainLen > maxPlainLen) {
        NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
        return nil;
    }
    
    void *plain = malloc(plainLen);
    [content getBytes:plain length:plainLen];
    
    size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
    void *cipher = malloc(cipherLen);
    
    OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain, plainLen, cipher, &cipherLen);
    
    NSData *result = nil;
    if (returnCode != 0)
        NSLog(@"SecKeyEncrypt fail. Error Code: %d", (int)returnCode);
    else
        result = [NSData dataWithBytes:cipher length:cipherLen];
    
    free(plain);
    free(cipher);
    
    return result;
}

///// 通过certificate获取SecKeyRef
//- (SecKeyRef)getPublicKey {
//
//    SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)self);
//    SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
//    SecTrustRef myTrust;
//    OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);
//    CFRelease(myPolicy);
//    CFRelease(myCertificate);
//    SecTrustResultType trustResult;
//    if (status == noErr) {
//        //        status = SecTrustEvaluate(myTrust, &trustResult);
//        SecTrustEvaluate(myTrust, &trustResult);
//    }
//    return SecTrustCopyPublicKey(myTrust);
//}

@end

#pragma mark - String Security

@implementation NSString (CLSecurity)

/// MD5加密函数
- (NSString *)md5
{
    return [CLSecurityHelper md5:self];
}

/// sha1加密函数 安全哈希算法
- (NSString *)sha1 {
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    return [CLSecurityHelper sha1:data];
}

///
- (NSString *)encryptRSAWithPublicKey:(SecKeyRef)publicKey maxPlainLen:(size_t)maxPlainLen
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    data = [data encryptRSAWithPublicKey:publicKey maxPlainLen:maxPlainLen];
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

@end


@implementation CLSecurityHelper

///
+ (NSString*)md5:(NSString*)string {

    const char *cStr = [string UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
    
    NSString *str2 = [NSString stringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]];
    
    return [str2 lowercaseString];
}

///
+ (NSString*)sha1:(NSData*)data {
    
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (CC_LONG)data.length, result);
    
    return [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15], result[16], result[17], result[18], result[19]];
}

@end

